home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / NeXTWORLD_DragLab / DragView.m < prev    next >
Text File  |  1995-06-12  |  7KB  |  273 lines

  1. //
  2. //    A View that implements Dragging in 3.0
  3. //    Greg Burd
  4. //        Copyright NeXT Computer, Inc 1992 All Rights Reserved
  5. //
  6. //    Created 7-4-92 -- (Improved from existing code by Randy Nelson)
  7. //
  8. //    You may freely copy, distribute and reuse the code in this example.
  9. //    NeXT disclaims any warranty of any kind, expressed or implied, as to
  10. //    its fitness for any particular use.
  11. //
  12.  
  13. #import "DragView.h"
  14. #import "Text_Console.h"        // text category that allows formated printf:
  15. #import <appkit/Application.h>
  16. #import <appkit/Pasteboard.h>
  17. #import <appkit/OpenPanel.h>
  18. #import <appkit/graphics.h>        // for NXFrameRectWithWidth
  19.  
  20. @implementation DragView
  21.  
  22. /*-------------------- methods to get things set up */
  23.  
  24. - initFrame:(const NXRect *)theFrame
  25. {
  26.     const char *const types[] = {NXPostScriptPboardType};
  27.     
  28.     [textObj printf:"In initFrame:\n"];
  29.     [super initFrame:theFrame];
  30.     
  31.     //register which pasteboard types you will accept
  32.     [self registerForDraggedTypes:(const char *const*)&types count:1];
  33.     drawBackground = YES;
  34.     
  35.     return self;
  36. }
  37.  
  38. - awakeFromNib
  39. {
  40.     [textObj printf:"In awakeFromNib:\n"];
  41.     
  42.     framed = NO;
  43.     [window makeKeyAndOrderFront:self];
  44.     return self;
  45. }
  46.  
  47. /*-------------------- methods to be the source of a dragging operation */
  48.  
  49. - mouseDown:(NXEvent *)theEvent
  50. {
  51.     NXPoint     zero = {0.0, 0.0};
  52.     id             thePboard;
  53.  
  54.     [textObj printf:"In mouseDown:\n"];
  55.     
  56.     // Prevent default window ordering (this is a new appkit feature)
  57.     [NXApp preventWindowOrdering];
  58.  
  59.     //get the Pboard
  60.     thePboard = [Pasteboard newName:NXDragPboard];
  61.     [thePboard declareTypes:&NXPostScriptPboardType num:1 owner:self];
  62.     
  63.     //put an EPS of the image on the Pboard
  64.     drawBackground = NO;
  65.     [self writePSCodeInside:&bounds to:thePboard];
  66.     drawBackground = YES;
  67.     
  68.     //start the drag
  69.     [self dragImage:theImage    // visable on screen during drag
  70.         at:&zero                // offset the mouse point for the drag
  71.         offset:&zero            // offset the inital mouse pt
  72.         event:theEvent            // theEvent structure
  73.         pasteboard:thePboard    // a Pasteboard with data on it
  74.         source:self                // source object
  75.         slideBack:YES];            // if no destination animate back to source
  76.     
  77.     return self;
  78. }
  79.  
  80. - draggedImage:(NXImage *)image beganAt:(NXPoint *)screenPoint
  81. {
  82.     [textObj printf:"In draggedImage::\n"];
  83.     return self;
  84. }
  85.  
  86. - (NXDragOperation)draggingSourceOperationMaskForLocal:(BOOL)flag
  87. {
  88.     [textObj printf:"In draggingSourceOperationMaskForLocal:\n"];
  89.     
  90.     return (NX_DragOperationCopy | NX_DragOperationGeneric);
  91. }
  92.  
  93. - draggedImage:(NXImage *)image endedAt:(NXPoint *)screenPoint deposited:(BOOL)flag
  94. {
  95.     [textObj printf:"In draggedImage:\n"];
  96.     
  97.     return self;
  98. }
  99.  
  100. /*-------------------- methods to be the destination of a dragging operation */
  101.  
  102. - (NXDragOperation)draggingEntered:sender
  103. {
  104.     [textObj printf:"In draggingEntered:\n"];
  105.  
  106.     // check to make sure we are not the source and this operation is a copy
  107.     if (([sender draggingSourceOperationMask] & NX_DragOperationCopy) &&
  108.                             ([sender draggingSource] != self)) {
  109.         framed = YES;
  110.         [self display];
  111.         //return the type of operation we want to do, this will dictate
  112.         //the type of cursor will show up when accepting the drag
  113.         return NX_DragOperationCopy;
  114.     }
  115.     return NX_DragOperationNone;
  116. }
  117.  
  118. - (NXDragOperation)draggingUpdated:sender
  119. {
  120.     [textObj printf:"In draggingUpdated:\n"];
  121.     
  122.     // make sure that this is a copy operation, and that this instance
  123.     // of DragView is not the source
  124.     if (([sender draggingSourceOperationMask] & NX_DragOperationCopy) &&
  125.                                     ([sender draggingSource] != self)) {
  126.         framed = YES;
  127.         [self display];
  128.         return NX_DragOperationCopy;
  129.     }
  130.     return NX_DragOperationNone;
  131. }
  132.  
  133. - draggingExited:sender
  134. {
  135.     [textObj printf:"In draggingExited:\n"];
  136.     if (framed) {
  137.         framed = NO;
  138.         [self display];
  139.     }
  140.     return self;
  141. }
  142.  
  143. - (BOOL)prepareForDragOperation:sender
  144. {
  145.     [textObj printf:"In performDragOperation:\n"];
  146.     
  147.     return YES;
  148. }
  149.  
  150. - (BOOL)performDragOperation:sender
  151. {
  152.     [textObj printf:"In performDragOperation:\n"];
  153.     
  154.     // make sure that what we are getting is from the same application
  155.     // and did not originate from this view.
  156.     if ([sender isDraggingSourceLocal] && ([sender draggingSource] != self)) {
  157.         
  158.         // if I had an image free it
  159.         if (theImage) [theImage free];
  160.     
  161.         // new call in NXImage allows you to initFromPasteboard
  162.         theImage = [[NXImage alloc] initFromPasteboard:
  163.                                         [sender draggingPasteboard]];
  164.         
  165.         [theImage setDataRetained:YES];    // otherwise it scales poorly
  166.         [theImage setScalable:YES];        // scaleable yes
  167.         [theImage setSize:&bounds.size];// rescale to the same size as view
  168.         framed = NO;
  169.         [self display];
  170.     }
  171.     if(framed) {
  172.         framed = NO;
  173.         [self display];
  174.     }
  175.     return YES;
  176. }
  177.  
  178. - concludeDragOperation:sender
  179. {
  180.     [textObj printf:"In concludeDragOperation:\n"];
  181.     // This is within a oneway call, so you can send a call to Workspace
  182.     // without it getting 'hung up' waiting for a return
  183.  
  184.     return self;
  185. }
  186.  
  187. /*-------------------- methods to display, and other useful stuff */
  188.  
  189. - (BOOL)acceptsFirstMouse
  190. {
  191.     [textObj printf:"In acceptsFirstMouse:\n"];
  192.     return YES;
  193. }
  194.  
  195. - (BOOL)shouldDelayWindowOrderingForEvent:(NXEvent *)theEvent
  196. {
  197.      // This is the other portion of the new appkit functionality
  198.     // which allows you to drag a partially obscure object without
  199.     // making the source window become main, and without making the
  200.     // source application the current app.
  201.     [textObj printf:"In shouldDelayWindowOrderingForEvent:\n"];
  202.     return YES;
  203. }
  204.  
  205. - sizeTo:(NXCoord)x :(NXCoord)y
  206. {
  207.     [textObj printf:"In sizeTo::\n"];
  208.     
  209.     [super sizeTo:x :y];
  210.     [theImage setSize:&bounds.size];
  211.     return self;    
  212. }
  213.  
  214. - open:sender
  215. {
  216.     static const char *const types[] = {"tiff", "eps", NULL};
  217.     
  218.     [textObj printf:"In open:\n"];
  219.     
  220.     // get a filename to open
  221.     if ([[OpenPanel new] runModalForTypes:types] == 0) return nil;
  222.         
  223.     // create an image from the file
  224.     // it'll be whatever size the file tells it to be
  225.     [self setImage:[[NXImage alloc] initFromFile:[[OpenPanel new] filename]]];
  226.     
  227.     return self;
  228. }
  229.  
  230. - setImage:(id)anImage
  231. {
  232.     [textObj printf:"In setImage:\n"];
  233.  
  234.     // free theImage it if is been used
  235.     if(theImage) [theImage free];
  236.     
  237.     framed = NO;
  238.     theImage = anImage;
  239.     [theImage setScalable:YES];        // scaleable yes
  240.     [theImage setSize:&bounds.size];    // rescale to the same size as view
  241.     [self display];
  242.  
  243.     return self;
  244. }
  245.  
  246. - drawSelf:(const NXRect *)rects :(int)num
  247. {    
  248.     // if we are copying the PS code onto the Pboard, then we don't want
  249.     // the white background.  Only the image.
  250.     if (drawBackground) NXEraseRect(rects);
  251.     
  252.     // Composite the image into the view.
  253.     [theImage composite:NX_SOVER toPoint:&bounds.origin];
  254.     // if we are in the middle of a drag operation then we can frame the
  255.     // view rect to show our acceptance of the incomming data.  Another way
  256.     // would be to create a ghost image similar to the shelf in Workspace.
  257.     if(framed) {
  258.         NXFrameRectWithWidth(&bounds, (NXCoord)3.0);
  259.     }
  260.     return self;
  261. }
  262.  
  263. - free
  264. {
  265.     [textObj printf:"In free:\n"];
  266.  
  267.     // be a good object and free things up
  268.     [theImage free];
  269.     return [super free];
  270. }
  271.  
  272. @end
  273.